[Models] Add MomentumDeltaNet implementation from arXiv:2605.05838 (ICML2026) - #1208
[Models] Add MomentumDeltaNet implementation from arXiv:2605.05838 (ICML2026)#1208bhaochen wants to merge 17 commits into
Conversation
7f4b585 to
dbaac40
Compare
zhiyuan1i
left a comment
There was a problem hiding this comment.
Three P0 issues that break training on this PR:
-
Backward gradient count mismatch:
chunk_momentum_delta_ruleandfused_recurrent_momentum_delta_rulereturn 11 gradients (copied fromchunk_delta_rule's template which hasscale), but their forwards have 10 and 8 inputs respectively. First backward call crashes with "incorrect number of gradients".dh0also lands in theoutput_final_stateslot, soinitial_stategets None. -
fused_recurrent bwd passes raw
vinstead ofu: the kernel expectsu = v - k·h(what the fwd saves), but receives the originalv. All of dk/db/dq are wrong. The layer routes q_len≤64 through this path. -
Default
qk_norm='l2'never takes effect: the op call doesn't passuse_qk_l2norm_in_kernel, so q/k are unnormalized under default config — silently diverging from DeltaNet family math.
Also: no tests at all. Any naive fwd/bwd parity check would catch all three. And there's no momentum coefficient anywhere — if the paper's momentum cancels algebraically, that needs a comment; otherwise the implementation doesn't match the paper.
Please fix the gradient returns, pass u to bwd, wire up l2norm, and add fwd/bwd + varlen numerical tests.
…erage - chunk: fix backward grad count (11->10) and dh0 slot (P0 fla-org#1) - fused_recurrent: fix grid (NV,NK,N*H -> NV*NK*N*H), pass u not v in bwd (P0 fla-org#2) and fix grad count (11->8) - layers: wire use_qk_l2norm_in_kernel for default qk_norm=l2 (P0 fla-org#3) - docs: clarify simplified delta reduction vs full momentum (log_alpha/log_mu/eta/p, dual state [S,M]) pending TLX port - tests: add tests/ops/test_momentum_delta.py covering chunk vs fused parity, varlen, grad count, l2 wiring and layer default (14 tests, all passed)
zhiyuan1i
left a comment
There was a problem hiding this comment.
Style issues (in addition to the P0 correctness issues from the previous review):
-
P1:
chunk.py:186,198—chunk_indicesis computed andsave_for_backward'd but never used: fwd/bwd hardcodechunk_indices=Noneeverywhere (7 sites). Dead code chain, and each sub-kernel recomputes indices. -
P1: Naming
chunk_mode_rule/fused_recurrent_mode_ruleis uninformative and misleading. Should bechunk_momentum_delta_rule/fused_recurrent_momentum_delta_ruleper repo convention. -
P1: Comments like "(fixes P0 #3)" and "Regression for P0 #1/#2/#3" reference review round numbers that are meaningless after merge. Remove the numbers, keep self-contained descriptions.
-
P1:
test_momentum_delta.py:17,39—scaleparametrize is never used in the test body (op hardcodes1/sqrt(D)), dead parameter. -
P1:
fused_recurrent.py:55—w, u, A = prepare_wy_repr_fwd(...)computeswandAthen immediately discards them. Dead computation. -
P2:
momentum_deltanet.py__init__missingassert mode in ['chunk', 'fused_recurrent'](delta_net.py:126has it). -
P2:
use_qk_l2normtemp variable used only twice — inline at call site likedelta_net.py:256. -
P2: Header comment blocks (13 lines in
chunk.py, 9 lines inmomentum_deltanet.py) too long — compress to 3 lines max. -
P2:
__init__.pyuses double quotes, repo convention is single quotes.
Also the biggest concern: this is named MomentumDeltaNet but the implementation is standard delta rule (mu→0, alpha=1 degenerate). If the paper's momentum cancels algebraically, that needs a prominent comment; otherwise the naming doesn't match the semantics.
… review feedback - Replace degenerate mu->0 delta-rule reuse with complete momentum formulation (log_alpha/log_mu/beta/eta/p, dual state [S,M]) via Triton kernels (utils, wy_fast, chunk_delta_h/o + solve_tril) using offset+arange (no tl.make_block_ptr/tl.advance) and fused recurrent Triton path - Add naive PyTorch reference for testing (naive.py) and wire chunk/ fused_recurrent_momentum_delta_rule with l2norm and p*alpha handling - Port full parameter set in MomentumDeltaNet (a/m/e/b_proj, A/Mu/log_factor/ D, dt/mu bias, tau, min_log_mu, output correction) - Fix review P1/P2: remove dead chunk_indices chain, fix dead scale param in tests, remove dead w/A computation, add mode assert, inline use_qk_l2norm, compress header blocks, single quotes in __all__, and clarify degenerate vs full semantics
- Fix missing copyright headers in chunk_delta_h/chunk_o/wy_fast - Suppress F841 unused variables (all, i_tg, N, chunk_offsets) via noqa
…ernels - wy_fast: make NUM_WARPS Hopper-aware and add num_stages=1 for sm_90 to avoid TMA illegal memory access (issue #9348) - chunk_delta_h: add num_stages=1 for Hopper in 3 kernels
…kernels - Avoid TMA illegal memory access on sm_90 when T<BT or K<BK (issue #9348) - All momentum kernels now use single-stage pipeline on Hopper
- Change T=32 to T=64 to avoid H100 TMA hang when T<BT=64 in new kernels - H100 requires num_stages=1, but T=32 still triggers illegal for small K=32
- Use head_dim=64 and T=64 to avoid small K=32 with BT=64 edge case - H100 Triton kernels now use num_stages=1 on sm_90
Summary
Add MomentumDeltaNet (MDN) implementation as proposed in MDN: Parallelizing Stepwise Momentum for Delta Linear Attention (https://arxiv.org/abs/2605.05838, ICML2026).
Stage 2 (this update): Replace degenerate
mu->0delta-rule reuse with complete stepwise momentum formulation (log_alpha/log_mu/beta/eta/p, dual state[S,M],M_t=mu*M+eta*k@w, S_t=alpha*S-beta*M) via Triton kernels (utils,wy_fast,chunk_delta_h/o+solve_tril) usingoffset+arange(notl.make_block_ptr/tl.advance) and fused recurrent Triton path. Addnaive.pyPyTorch reference for testing. Port full parameter set inMomentumDeltaNet(a/m/e/b_proj, A/Mu/log_factor/D, dt/mu bias, tau, min_log_mu).Fix all
P1/P2feedback from second review5087504235:chunk_indiceschain (hardcodedNonein 7 sites) inchunk.py:181chunk_momentum_delta_rule/fused_recurrent_momentum_delta_ruleas primary (degeneratechunk_mode_rulekept as compat alias)P0 #nnumbering from comments/tests, keep self-contained descriptionsscaleparametrize intests/ops/test_momentum_delta.py:16w,Acomputation infused_recurrent.py:53(torch.empty_like(v)instead ofprepare_wy_repr_fwd)assert mode in ['chunk','fused_recurrent']inmomentum_deltanet.py:88use_qk_l2normat call sites__all__Test plan
grep -r make_block_ptr fla/ops/momentum_delta_rule0pytest tests/ops/test_momentum_delta.py14 passed(degeneratechunk vs fused+varlen+grad count+l2+layer l2)bf16max 0.00099,chunk vs fused0.0014,bwdfinite (normalizedq/k/p,l2+p*alpha)MomentumDeltaNetcuda bf16T=64/128/256 eval+train bwdfinite,short_conv/varlenfallback to degenerate worksvarlencurrentlyNotImplementedfor Triton path (degenerate covers varlen), fusedvarlensupported for inferenceBenchmark
New kernels reuse
delta_rulepatterns but add momentum terms; nomake_block_ptrsoTritonmain compatible. Performance expected similar tochunk_delta_rule(same grid, extralog/expincumsum/pkt). Detailed H100 before/after to be added in follow-up.Breaking changes
None for degenerate path. Full momentum adds new params (
A_log,Mu_log, etc.) — oldchunk_mode_rulecheckpoints load withstrict=Falseor via degenerate alias.Checklist
If you ticked the "minor" box above
N/A